package com.example.spotitube.View;

import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.Collections;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import android.app.ListActivity;
import android.app.ProgressDialog;
import android.content.Context;
import android.content.Intent;
import android.content.pm.ActivityInfo;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.Window;
import android.view.WindowManager;
import android.view.inputmethod.InputMethodManager;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;
import android.widget.ToggleButton;

import com.example.spotitube.R;
import com.example.spotitube.Connection.Connection;
import com.example.spotitube.Controller.AlbumListAdapter;
import com.example.spotitube.Controller.LengthComparator;
import com.example.spotitube.Controller.ListAdapter;
import com.example.spotitube.Controller.PopularityComparator;
import com.example.spotitube.Controller.ReleaseYearComparator;
import com.example.spotitube.Controller.TitleComparator;
import com.example.spotitube.Model.Track;


public class MainActivity extends ListActivity implements OnClickListener{
	
	private ProgressDialog	progressDialog;
	private Handler			handler;
	public static final int	PERFECT_MATCH	= 1, MULTIPLE_MATCHES = 2, FAILED = -1;
	private boolean			reverse;
	
	
	@Override
	public void onCreate( Bundle savedInstanceState ) {
		super.onCreate( savedInstanceState );
		
		// Don't show title and always show in portrait modus
		setRequestedOrientation( ActivityInfo.SCREEN_ORIENTATION_PORTRAIT );
		requestWindowFeature( Window.FEATURE_NO_TITLE );
		getWindow().setFlags( WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN );
		
		setContentView( R.layout.activity_main );
		
		setListAdapter( new ListAdapter( this, R.layout.list_item, new ArrayList<Track>() ) );
		
		// Handler that gets his data from the Connection class in the
		// onPostExecute
		handler = new Handler( new Handler.Callback(){
			
			@SuppressWarnings( "unchecked" )
			@Override
			public boolean handleMessage( Message msg ) {
				switch( msg.what ){
					case FAILED:
						break;
					case PERFECT_MATCH:
						// when the artist filled in is a full match
						showTracks( ( ArrayList<Track> ) msg.obj );
						handler.removeMessages( 1 );
						break;
					case MULTIPLE_MATCHES:
						// when the artist filled in has several matches
						showArtistSuggestions( ( ArrayList<String> ) msg.obj );
						handler.removeMessages( 2 );
						break;
					default:
						break;
				}
				progressDialog.dismiss();
				return false;
			}
		} );
	}
	
	
	@SuppressWarnings( "unchecked" )
	public void onClick( View v ) {
		
		hasConnection();
		TextView artist = ( TextView ) findViewById( R.id.artistField );
		
		switch( v.getId() ){
		
			case R.id.searchButton:
				InputMethodManager imm = ( InputMethodManager ) getSystemService( Context.INPUT_METHOD_SERVICE );
				imm.hideSoftInputFromWindow( v.getWindowToken(), 0 );
				
				progressDialog = ProgressDialog.show( this, "", "Retrieving data..." );
				new Connection( handler ).execute( artist.getText(), "artist" );
				break;
			case R.id.sortLength:
				ListAdapter trackAdapter = ( ListAdapter ) getListAdapter();
				setListAdapter( new ListAdapter( getApplicationContext(), R.layout.list_item, sort( trackAdapter.getTracks(), "length",
						reverse ) ) );
				( ( ArrayAdapter<Track> ) getListAdapter() ).notifyDataSetChanged();
				getListView().invalidate();
				reverse = !reverse;
				break;
			case R.id.sortPopularity:
				ListAdapter trackAdapter2 = ( ListAdapter ) getListAdapter();
				setListAdapter( new ListAdapter( getApplicationContext(), R.layout.list_item, sort( trackAdapter2.getTracks(),
						"popularity", reverse ) ) );
				( ( ArrayAdapter<Track> ) getListAdapter() ).notifyDataSetChanged();
				getListView().invalidate();
				reverse = !reverse;
				break;
			case R.id.sortReleaseYear:
				ListAdapter trackAdapter3 = ( ListAdapter ) getListAdapter();
				setListAdapter( new ListAdapter( getApplicationContext(), R.layout.list_item, sort( trackAdapter3.getTracks(),
						"releaseYear", reverse ) ) );
				( ( ArrayAdapter<Track> ) getListAdapter() ).notifyDataSetChanged();
				getListView().invalidate();
				reverse = !reverse;
				break;
			case R.id.sortTitle:
				ListAdapter trackAdapter4 = ( ListAdapter ) getListAdapter();
				setListAdapter( new ListAdapter( getApplicationContext(), R.layout.list_item, sort( trackAdapter4.getTracks(), "title",
						reverse ) ) );
				( ( ArrayAdapter<Track> ) getListAdapter() ).notifyDataSetChanged();
				getListView().invalidate();
				reverse = !reverse;
				break;
			case R.id.toggleButton:
				//Jeffrey
				//if the button is checked, get an albumlistadapter to show the albums
				if( ( ( ToggleButton ) v ).isChecked() ){
					
					try{
						setListAdapter( new AlbumListAdapter( getApplicationContext(), R.layout.list_item, getAlbums( artist.getText()
								.toString() ) ) );
						artist = ( TextView ) findViewById( R.id.artistField );
					} catch( JSONException e ){
						System.out.println( "Toggle albums error!" );
						e.printStackTrace();
					}
					
				} else{
					//else search again for tracks
					progressDialog = ProgressDialog.show( this, "", "Retrieving data..." );
					artist = ( TextView ) findViewById( R.id.artistField );
					new Connection( handler ).execute( artist.getText() );
				}
				break;
			default:
				break;
		}
	}
	
	
	/**
	 * shows the tracks on the screen
	 * 
	 * @param tracks
	 */
	public void showTracks( ArrayList<Track> tracks ) {
		setListAdapter( new ListAdapter( getApplicationContext(), R.layout.list_item, tracks ) );
		( ( ArrayAdapter<Track> ) getListAdapter() ).notifyDataSetChanged();
		getListView().invalidate();
	}
	
	
	/**
	 * shown when there are suggestions for the artist filled in
	 * 
	 * @param artists
	 */
	public void showArtistSuggestions( ArrayList<String> artists ) {
		SuggestedArtistDialog suggestedArtistsDialog = new SuggestedArtistDialog( artists, this, this );
		suggestedArtistsDialog.showDialog();
	}
	
	
	// Jeffrey
	public boolean hasConnection() {
		ConnectivityManager cm = ( ConnectivityManager ) getSystemService( Context.CONNECTIVITY_SERVICE );
		NetworkInfo netInfo = cm.getActiveNetworkInfo();
		if( netInfo != null && netInfo.isConnectedOrConnecting() ){
			return true;
		}
		Toast.makeText( this, "You have no internet access. Please check your settings and try again.", Toast.LENGTH_LONG ).show();
		return false;
	}
	
	
	@Override
	public void onListItemClick( ListView l, View v, int position, long id ) {
		if( l.getItemAtPosition( position ) instanceof Track ){
			Intent intent = new Intent( this, TrackDetailActivity.class );
			Track track = ( Track ) l.getItemAtPosition( position );
			intent.putExtra( "track", track );
			startActivity( intent );
		} else if(l.getItemAtPosition( position ) instanceof String){
			Intent intent = new Intent( this, AlbumDetailActivity.class );
			String albumName = ( String ) l.getItemAtPosition( position );
			intent.putExtra( "albumName", albumName );
			startActivity( intent );
		}
		
	}
	
	//Jeffrey
	//sorts an arraylist of track by title, lenth, release year or popularity
	public ArrayList<Track> sort( ArrayList<Track> allTracks, String sorter, boolean reverse ) {
		ArrayList<Track> list = allTracks;
		if( sorter.equals( "title" ) ){
			Collections.sort( list, new TitleComparator() );
		} else if( sorter.equals( "length" ) ){
			Collections.sort( list, new LengthComparator() );
		} else if( sorter.equals( "releaseYear" ) ){
			Collections.sort( list, new ReleaseYearComparator() );
		} else if( sorter.equals( "popularity" ) ){
			Collections.sort( list, new PopularityComparator() );
		}
		if( reverse ){
			Collections.reverse( list );
		}
		return list;
	}
	
	
	public void setArtistToSearch( String result ) {
		TextView artistSearchField = ( TextView ) findViewById( R.id.artistField );
		artistSearchField.setText( result );
		
		Button search = ( Button ) findViewById( R.id.searchButton );
		search.performClick();
	}
	
	
	public ArrayList<String> getAlbums( String artist ) throws JSONException {
		String encodedArtist = URLEncoder.encode( artist );
		JSONObject all = Connection.getJson( "http://ws.spotify.com/search/1/track.json?page=1&q=artist:" + encodedArtist );
		JSONArray tracks = all.getJSONArray( "tracks" );
		ArrayList<String> albums = new ArrayList<String>();
		for( int i = 0; i < tracks.length(); i++ ){
			String albumName = tracks.getJSONObject( i ).getJSONObject( "album" ).getString( "name" );
			if( !albums.contains( albumName ) ){
				albums.add( albumName );
			}
		}
		return albums;
	}
}
